#ifndef G3_MULTITHREADING_H
#define G3_MULTITHREADING_H

#include <set>
#include <boost/thread/thread.hpp>
#include "log.h"

namespace G3 {

class THREAD_OBJECT:public LOGGABLE {
	public:
		THREAD_OBJECT () {
			online = false;
		}

        virtual ~THREAD_OBJECT () {
            online = false;
        }

        /**
            @brief Checks if the thread is online
            @return True if it is and false if it is not
        */
        bool IsOnline () {
			return online;
		}

		virtual void dump () {
		    if (log)
                log->Report ("Dumping THREAD_OBJECT:\n online = %d\n", online);
		}

        /** Pointer to the streamer thread */
        boost::shared_ptr<boost::thread> thread;

		virtual void process () {
			Assert (false, "THREAD_OBJECT::Process called as a pure virtual..\n");
		}

	protected:
        /** Is the sorter thread online ? */
        volatile bool online;
};

template<class TClass>
boost::shared_ptr<TClass> StartThread () {
    boost::shared_ptr<TClass> ptr (new TClass);
    boost::shared_ptr<boost::thread> thread (new boost::thread (boost::bind (&TClass::process, ptr)));
    ptr->thread = thread;
    return ptr;
}

template<class TClass>
void StopThread (boost::shared_ptr<TClass> ptr) {
    Assert (ptr, "Trying to stop a thread with a NULL shared pointer..\n");
    Assert (ptr->thread, "Trying to stop a non-existent thread..\n");

    ptr->thread->join ();
}

}

#endif
